package net.liteheaven.xblib.widget.Toast;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Build;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;

import net.liteheaven.xblib.common.ui.DimensionUtil;

/**
 *
 * Custom defined Toast base class
 *
 * @author LiangYu
 */
public class SmartToast {

    private static final String TAG = "SmartToast";

    public static Class<?> INTERPOLATOR_LIST [] = {
            LinearInterpolator.class,
            AccelerateDecelerateInterpolator.class,
            AccelerateInterpolator.class,
            AnticipateInterpolator.class,
            AnticipateOvershootInterpolator.class,
            BounceInterpolator.class,
            CycleInterpolator.class,
            DecelerateInterpolator.class,
            OvershootInterpolator.class
    };

    protected Handler mHandler;
    protected boolean mIsShow;
    protected static SmartToast mLastToast = null;
    protected Context mCtx;
    protected int mDuration;
    protected WindowManager mWindowManager;
    protected View mToastView;
    protected WindowManager.LayoutParams mParams;
    protected int mInterpolatorIndex = 0;

    protected SmartToast(Context context, String text, int duration){

        mCtx = context.getApplicationContext();
        mDuration = duration;
        mToastView = Toast.makeText(mCtx, text, Toast.LENGTH_SHORT).getView();
        init();
    }

    protected SmartToast(Context context, View v, int duration){

        mCtx = context.getApplicationContext();
        mToastView = v;
        mDuration = duration;
        init();
    }

    private void init(){
        mHandler = new Handler();
        mIsShow = false;
        mWindowManager = (WindowManager) mCtx.getSystemService(Context.WINDOW_SERVICE);
        setParams();
    }

    private void setParams() {
        mParams = new WindowManager.LayoutParams();
        mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        mParams.format = PixelFormat.TRANSLUCENT;

        //
        // 使用各个厂商自己的默认动画
        // mParams.windowAnimations = android.R.style.Animation_Toast;
        //
        // case 1.在WindowManager的Context为Activity时
        // 可以使用自定义布局,但是不符合需求
        // Context声明周期过短，在活动finish时会抛出异常
        //
        // case 2.在WindowManager的Context为Application时
        // 不允许使用自定义布局
        // 无法改变Toast默认动画
        // mParams.windowAnimations = R.style.anim_miui_toast;
        //

        // 8.0适配
        mParams.type = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_TOAST;
        mParams.setTitle("Toast");
        mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

        mParams.gravity = Gravity.TOP;
        mParams.y = 0;
    }

    protected void onStart(){
        final int animEnterInterval = 500;
        long interval = (mDuration == Toast.LENGTH_LONG) ? 3500 : 2000;
        if (interval < animEnterInterval){
            interval = animEnterInterval;
        }

        Point sc = DimensionUtil.getScreenSize(mCtx);
        mToastView.measure(0,0);

        int toastHeight = mToastView.getMeasuredHeight();
        int start = sc.y - DimensionUtil.getStatusBarHeight(mCtx) - toastHeight- getYStart();
        int end = start - getYTranslation();
        PropertyValuesHolder h = PropertyValuesHolder.ofInt("offsetY", start, end);

        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(this, h);
        TimeInterpolator interpolator = getInterpolator(mInterpolatorIndex);
        oa.setInterpolator(interpolator);

        oa.setDuration(animEnterInterval);
        oa.start();

        Runnable runnableCancel = new Runnable() {
            @Override
            public void run() {
                cancel();
            }
        };
        mHandler.postDelayed(runnableCancel, interval);
    }

    public void show(){
        if(!mIsShow){//如果Toast没有显示，则开始加载显示
            mIsShow = true;
            mWindowManager.addView(mToastView, mParams);//将其加载到windowManager上

            mHandler.removeCallbacksAndMessages(null);
            onStart();
            mLastToast = this;
        }
    }

    public void cancel(){
        if (mIsShow){
            mWindowManager.removeView(mToastView);
            mIsShow = false;
        }
    }

    public View getView(){
        return mToastView;
    }

    protected void setOffsetY(int y){
        if (mIsShow){
            mParams.y = y;
            mWindowManager.updateViewLayout(mToastView, mParams);
        }
    }

    protected void setAlpha(float a){
        if (mIsShow){
            mParams.alpha = a;
            mWindowManager.updateViewLayout(mToastView, mParams);
        }
    }

    public void setInterpolatorIndex(int index){
        if (index >= INTERPOLATOR_LIST.length){
            index = 0;
        }
        if (index < 0){
            index = 0;
        }
        mInterpolatorIndex = index;
    }

    protected static TimeInterpolator getInterpolator(int index){
        TimeInterpolator interpolator = null;
        try {
            interpolator = (TimeInterpolator)INTERPOLATOR_LIST[index].newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            interpolator = null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            interpolator = null;
        }
        return interpolator;
    }

    public static void cancelLastToast(){
        if (mLastToast!=null){
            mLastToast.cancel();
            mLastToast = null;
        }
    }

    protected int getYTranslation(){
        return DimensionUtil.dip2px(mCtx, 40);
    }

    protected int getYStart(){
        return DimensionUtil.dip2px(mCtx, 64);
    }
}
